numa: Correct handling node with CPU populated but no memory populated
authorKeir Fraser <keir.fraser@citrix.com>
Tue, 5 Jan 2010 08:38:23 +0000 (08:38 +0000)
committerKeir Fraser <keir.fraser@citrix.com>
Tue, 5 Jan 2010 08:38:23 +0000 (08:38 +0000)
In changeset 20599, the node that has no memory populated is marked
parsed, but not online. However, if there are CPU populated in this
node, the corresponding CPU mapping (i.e. the cpu_to_node) is still
setup to the offline node, this will cause trouble for memory
allocation.

This patch changes the init_cpu_to_node() and srant_detect_node(), to
considering the node is offlined situation.

Now the apicid_to_node is only used to keep the mapping between
cpu/node provided by BIOS, and should not be used for memory
allocation anymore.

One thing left is to update the cpu_to_node mapping after memory
populated by memory hot-add.

Signed-off-by: Jiang, Yunhong <yunhong.jiang@intel.com>
This is a reintroduction of 20726:ddb8c5e798f9, which I incorrectly
reverted in 20745:d3215a968db9

Signed-off-by: Keir Fraser <keir.fraser@citrix.com>
xen/arch/x86/numa.c
xen/arch/x86/setup.c
xen/arch/x86/smpboot.c
xen/arch/x86/x86_64/mm.c

index 676ff37001ed7f26e75ea54242fa0cf0e61f71e9..6810b484caa20d796a08ab6a78fa37ab4fd28219 100644 (file)
@@ -35,6 +35,9 @@ u8  memnodemap[NODEMAPSIZE];
 unsigned char cpu_to_node[NR_CPUS] __read_mostly = {
        [0 ... NR_CPUS-1] = NUMA_NO_NODE
 };
+/*
+ * Keep BIOS's CPU2node information, should not be used for memory allocaion
+ */
 unsigned char apicid_to_node[MAX_LOCAL_APIC] __cpuinitdata = {
        [0 ... MAX_LOCAL_APIC-1] = NUMA_NO_NODE
 };
@@ -288,14 +291,15 @@ static __init int numa_setup(char *opt)
  */
 void __devinit init_cpu_to_node(void)
 {
-       int i;
+       int i, node;
        for (i = 0; i < NR_CPUS; i++) {
                u32 apicid = x86_cpu_to_apicid[i];
                if (apicid == BAD_APICID)
                        continue;
-               if (apicid_to_node[apicid] == NUMA_NO_NODE)
-                       continue;
-               numa_set_node(i,apicid_to_node[apicid]);
+               node = apicid_to_node[apicid];
+               if ( node == NUMA_NO_NODE || !node_online(node) )
+                       node = 0;
+               numa_set_node(i, node);
        }
 }
 
index 5956dfcc05bc1c12dcbeecbcae0d5e69a4a36ecc..38a0f5cd398c8dca710fae41620a291b29787b72 100644 (file)
@@ -20,6 +20,7 @@
 #include <xen/rcupdate.h>
 #include <xen/vga.h>
 #include <xen/dmi.h>
+#include <xen/nodemask.h>
 #include <public/version.h>
 #ifdef CONFIG_COMPAT
 #include <compat/platform.h>
@@ -263,7 +264,7 @@ void __devinit srat_detect_node(int cpu)
     u32 apicid = x86_cpu_to_apicid[cpu];
 
     node = apicid_to_node[apicid];
-    if ( node == NUMA_NO_NODE )
+    if ( node == NUMA_NO_NODE || !node_online(node) )
         node = 0;
     numa_set_node(cpu, node);
 
index 5220d5173a1c230b580fac99af3e92fbe01514bc..ce18c7f0bef77f2b382275db3e77a56a4b7a44b9 100644 (file)
@@ -913,7 +913,7 @@ static int __devinit do_boot_cpu(int apicid, int cpu)
        }
 #else
        if (!per_cpu(compat_arg_xlat, cpu))
-               setup_compat_arg_xlat(cpu, apicid_to_node[apicid]);
+               setup_compat_arg_xlat(cpu, cpu_to_node[cpu]);
 #endif
 
        if (!idt_tables[cpu]) {
index dfa12ad1710c04c687ede9497251b2ccdb06c9ff..03b61cc34f7aa471b9b65a818bf6280395c3e69e 100644 (file)
@@ -997,7 +997,7 @@ void __init subarch_init_memory(void)
     }
 
     if ( setup_compat_arg_xlat(smp_processor_id(),
-                               apicid_to_node[boot_cpu_physical_apicid]) )
+                               cpu_to_node[0]) )
         panic("Could not setup argument translation area");
 }